/*************************************************************************
                           pmBuffer  -  description
                             -------------------
    début                : 30 déc. 2009
    copyright            : (C) 2009 par nico
 *************************************************************************/

//---------- Interface de la classe <pmBuffer> (fichier pmBuffer.h) ------
#ifndef PMBUFFER_H_
#define PMBUFFER_H_

//--------------------------------------------------- Interfaces utilisées
#include "pmElement.h"
#include <string>

//------------------------------------------------------------- Constantes

//------------------------------------------------------------------ Types

//------------------------------------------------------------------------
// Rôle de la classe <pmBuffer>
//
//
//------------------------------------------------------------------------
template <class T = double> class pmBuffer : public pmElement<T>
{
	//----------------------------------------------------------------- PUBLIC
public:
	//----------------------------------------------------- Méthodes publiques
	T GetValue(int index1 = 0, int index2 = 0, int index3 = 0);
	bool SetValue(T value, int index1 = 0, int index2 = 0, int index3 = 0);
	unsigned GetDimension();
	unsigned GetSize(unsigned dimIndex = 1);
	bool CopyData(T* dataPtr);
	//------------------------------------------------- Surcharge d'opérateurs
	/*pmBuffer & operator = ( const pmBuffer & unpmBuffer );

	//-------------------------------------------- Constructeurs - destructeur
	pmBuffer ( const pmBuffer & unpmBuffer );*/
	pmBuffer ( std::string name, unsigned size1, unsigned size2 = 1, unsigned size3 = 1);
	~pmBuffer ( );

protected:
	//----------------------------------------------------- Méthodes protégées
	//----------------------------------------------------- Attributs protégés
	T* m_data;
	unsigned m_dim;
	unsigned m_size1;
	unsigned m_size2;
	unsigned m_size3;
};




/********************************************************************
 *		Implementation
 *
 *********************************************************************/
using namespace std;

template <class T>
T pmBuffer<T>::GetValue(int index1, int index2, int index3 )
{
#ifdef appDEBUG
	cout << "appel de pmBuffer::GetValue" << endl;
#endif
	int position = index1+(index2*m_size2)+(index3*m_size2*m_size3);
	//if the index value si out of the buffer ...
	if( (position < 0) || (position > m_size1*m_size2*m_size3) )
		return 0;

	return m_data[position];
}

template <class T>
bool pmBuffer<T>::SetValue(T value, int index1 , int index2 , int index3 )
{
	if((index1 + 1 > m_size1)||(index2 + 2 > m_size1)||(index3 + 1 > m_size3)) return false;
	m_data[index1+(index2*m_size2)+(index3*m_size2*m_size3)] = value;
	return true;
}

template <class T> unsigned pmBuffer<T>::GetDimension() {return m_dim;}

template <class T> unsigned pmBuffer<T>::GetSize(unsigned dimIndex)
{
	switch(dimIndex)
	{
	case 1: {return m_size1; break;}
	case 2: {return m_size2; break;}
	case 3: {return m_size3; break;}
	default: {return 0; break;}
	}
}

template <class T> bool pmBuffer<T>::CopyData(T* dataPtr)
{
	unsigned size = m_size1*m_size2*m_size3;
	for(unsigned i = 0; i < size; ++i)
		m_data[i]=dataPtr[i];

	return true; // TODO: handle enventual erros
}

template <class T> pmBuffer<T>::pmBuffer(string name, unsigned size1, unsigned size2, unsigned size3)
{
	pmElement<T>::m_name = name;


	m_size1 = size1;
	m_size2 = size2;
	m_size3 = size3;

	m_dim=1;
	if(size1 < 2) {m_size1 = 1;}

	if(size2 < 2) {m_size2 = 1;}
	else m_dim += 1;

	if(size3 < 2) {m_size3 = 1;}
	else m_dim += 1;

	int totalSize = m_size1*m_size2*m_size3;
	m_data = new T[totalSize];
	for(int i = 0; i< totalSize; ++i) m_data[i] = 0;
}

template <class T> pmBuffer<T>::~pmBuffer()
{
	//unsigned size = m_size1*m_size2*m_size3;
	//for(unsigned i = 0; i < size; ++i)
	delete[] m_data;
}





#endif // PMBUFFER_H_
